package org.visionlibrary.image.model;

import java.awt.Point;

import javax.media.jai.TiledImage;

import org.visionlibrary.image.acquisition.ImageFactory;



abstract public class WindowFilter extends AbstractFilter {
	protected int windowWidth;
	protected int windowHeight;
	protected Point dstPointInWindow;
	protected Point actualPixel = new Point(0, 0);

	public TiledImage applyFilter(TiledImage src, TiledImage dest) {
		if(null == src)
			throw new NullPointerException("Source image is null.");
		
		if(null == dest)
			dest = (new ImageFactory()).createCompatibleImage(src);
		
		setWindowProperties();

		int minX = dstPointInWindow.x;
		int maxX = src.getWidth() - (windowWidth - dstPointInWindow.x);
		int minY = dstPointInWindow.y;
		int maxY = src.getHeight() - (windowHeight - dstPointInWindow.y);
		for (int ch = 0; ch < src.getNumBands(); ch++)
			for (this.actualPixel.x = minX; this.actualPixel.x < maxX; this.actualPixel.x++)
				for (this.actualPixel.y = minY; this.actualPixel.y < maxY; this.actualPixel.y++) {
					int newPixelVal = getNewPixelVal(src,
							new Point(actualPixel), ch);
					int normalizedPixelVal = normalization
							.normalize(newPixelVal);
					dest.setSample(this.actualPixel.x, this.actualPixel.y, ch,
							normalizedPixelVal);
				}

		return dest;
	}

	protected Point WindowToImageCoord(Point windowCoord) {
		int x = windowCoord.x + (actualPixel.x - dstPointInWindow.x);
		int y = windowCoord.y + (actualPixel.y - dstPointInWindow.y);

		return new Point(x, y);
	}

	protected int getWindowPixelVal(TiledImage src, Point windowCoord,
			int channel) {
		Point windowPoint = WindowToImageCoord(windowCoord);
		return src.getSample(windowPoint.x, windowPoint.y, channel);
	}

	abstract protected int getNewPixelVal(TiledImage src, Point p, int channel);

	abstract protected void setWindowProperties();
}
